#ifndef STRING__ZHU_H
#define STRING__ZHU_H
#include <iostream>
using namespace std;
class Cref;
class String
{
    struct Srep;
    Srep* _rep;
public:
    class Range{};
    friend class String_sub;
    friend class String_iter;
    
    String();
    String(const char*);
    String(const String&);
    String& operator=(const char*);
    String& operator=(const String&);
    ~String();

    void check(int i)const;
    char read(int i)const;
    void write(int, char c);
    Cref operator[](int i);
    char operator[](int i)const;
    const String operator()(int left, int right)const;
    String_sub operator()(int left, int right);

    const char* c_string();
    int size()const;
    String& operator+=(const String&);
    String& operator+=(const char*);
    
    friend ostream& operator<<(ostream&, const String&);
    friend istream& operator>>(istream&, String&);
    
    friend bool operator==(const String& x, const char* s);
    friend bool operator==(const String& x, const String& y);
    friend bool operator!=(const String& x,const char* s);
    friend bool operator!=(const String&x, const String& y);
    friend String operator+(const String&, const String&);
    friend String operator+(const String&, const char*);
};

class Cref
{
    friend class String;
    friend class String_iter;
    
    String& _str;
    int _i;
    Cref(String& str, int i):_str(str),_i(i){}
public:
    operator char(){//yield value
        return _str.read(_i);
    }
    void operator= (char c){//change value
        _str.write(_i,c);
    }
};    
class String_iter
{
    int _index;
    String& _str;
public:
    String_iter(String& str):_str(str),_index(0){}
    Cref next(){
        return Cref(_str, _index++);
    }
    void reset(){
        _index = 0;
    }
};
class String_sub
{
    friend class String;
    String& _str;
    int _left,_right;
    String_sub(String& str,int left, int right):
    _str(str),_left(left),_right(right){
    }
public:
    String& operator=(const char* s);
    friend ostream& operator<<(ostream& os, const String_sub& sub);
};


#endif


    
